package controller;

import java.util.ArrayList;

import exception.FinDePartie;
import exception.SelectionImpossible;
import vue.FenetrePrincipale;
import vue.ObserveurJoueur;
import vue.ObserveurPlateau;
import model.Case;
import model.Direction;
import model.Joueur;
import model.Plateau;
import model.elfes.CreateurElfe;
import model.orcs.CreateurOrc;


/**
 * Class Controleur
 */
public class Controleur {

	
	private static final int NB_AC_DEF = 3;
	private static final int NB_TOUR = 10;
	public int getNbAcction() {
		return nbAcction;
	}

	public int getNbTour() {
		return nbTour;
	}

	// D�finir les fonctions telque selectionner (int x, int y) une case
	// Fields
	//
	private boolean attaquer=true;
	private static Controleur controleur;
	private Plateau plateau;
	private FenetrePrincipale fenetre;
	//private Personnage personnage;
	private ArrayList<Joueur> joueurs;
	private int numJoueur=0;
	private int x, y;
	private int nbAcction=NB_AC_DEF;
	private int nbTour=NB_TOUR;
	
	//
	// Constructors
	//
	private Controleur () {
		
	}

	//
	// Methods
	//
	
	
	
	
	
	//Getters and setters
	
	public Plateau getPlateau() {
		return plateau;
	}

	public void setPlateau(Plateau plateau) {
		this.plateau = plateau;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}
	
	//Other methods

	
	public void selectionnerCase(int x, int y) throws SelectionImpossible, FinDePartie{
		if(plateau.getCases()[x][y].isCible()) {
			if(attaquer)
				attaquer(x, y);
			else
				deplacer(x, y);
			if (nbAcction<=0) {
				if (numJoueur==1)
					nbTour--;
				if (nbTour<=0) {
					throw new FinDePartie("Le vainqueur et celui qui � la plus de vitalit�.");
				}
				numJoueur=(numJoueur+1)%2;
				nbAcction=NB_AC_DEF;
			}
		}
		else {
			if(plateau.getCases()[x][y].getPerso().getJoueur()!=joueurs.get(numJoueur))
				throw new SelectionImpossible("Pas le bon joueur");
			plateau.setSelectionner(x, y, attaquer);
		}
	}
	
	private void deplacer(int x2, int y2) {
		Case c = plateau.getCases()[x2][y2];
		if (plateau.getCases()[x2][y2].getPerso()==null) {
			plateau.moveTo(c);
			nbAcction--;
		}
	}

//	public void selection(Case c){
//		position = c;
//	}
	
	private void attaquer(int x2, int y2) {
		Case c = plateau.getCases()[x2][y2];
		if (plateau.getCases()[x2][y2].getPerso().getJoueur()!=joueurs.get(numJoueur)) {
			plateau.getPosition().getPerso().attaquer(c);
			nbAcction--;
		}
		plateau.clearSelect();
	}

	public void nouvellePartie(ObserveurPlateau obsP, ObserveurJoueur obsJ, FenetrePrincipale fenetre){
		
		plateau = new Plateau();
		this.fenetre=fenetre;
		plateau.ajouterObs(fenetre);
		plateau.ajouterObs(obsP);
		joueurs = new ArrayList<Joueur>();
		joueurs.add(new Joueur(new CreateurElfe(),1));
		joueurs.add(new Joueur(new CreateurOrc(),2));
		joueurs.get(0).getFabrique().setDirection(Direction.SUD);
		joueurs.get(1).getFabrique().setDirection(Direction.NORD);
		joueurs.get(0).ajouterObs(obsJ);
		joueurs.get(1).ajouterObs(obsJ);
		joueurs.get(0).ajouterPerso(joueurs.get(0).getFabrique().creerArcher(plateau.getCases()[1][1]));
		joueurs.get(0).ajouterPerso(joueurs.get(0).getFabrique().creerArcher(plateau.getCases()[3][1]));
		joueurs.get(0).ajouterPerso(joueurs.get(0).getFabrique().creerArcher(plateau.getCases()[5][1]));
		joueurs.get(0).ajouterPerso(joueurs.get(0).getFabrique().creerArcher(plateau.getCases()[7][1]));
		joueurs.get(0).ajouterPerso(joueurs.get(0).getFabrique().CreerChevalier(plateau.getCases()[2][0]));
		joueurs.get(0).ajouterPerso(joueurs.get(0).getFabrique().CreerChevalier(plateau.getCases()[4][0]));
		joueurs.get(0).ajouterPerso(joueurs.get(0).getFabrique().CreerGuerrier(plateau.getCases()[6][0]));
		joueurs.get(1).ajouterPerso(joueurs.get(1).getFabrique().creerArcher(plateau.getCases()[1][6]));
		joueurs.get(1).ajouterPerso(joueurs.get(1).getFabrique().creerArcher(plateau.getCases()[3][6]));
		joueurs.get(1).ajouterPerso(joueurs.get(1).getFabrique().creerArcher(plateau.getCases()[5][6]));
		joueurs.get(1).ajouterPerso(joueurs.get(1).getFabrique().creerArcher(plateau.getCases()[7][6]));
		joueurs.get(1).ajouterPerso(joueurs.get(1).getFabrique().CreerChevalier(plateau.getCases()[2][7]));
		joueurs.get(1).ajouterPerso(joueurs.get(1).getFabrique().CreerChevalier(plateau.getCases()[4][7]));
		joueurs.get(1).ajouterPerso(joueurs.get(1).getFabrique().CreerGuerrier(plateau.getCases()[6][7]));
		plateau.signaleCration();
		
	}
	
	public static Controleur getControleur() {
		if (controleur == null) {
			controleur = new Controleur();
		}
		return controleur;
	}

	public boolean isAttaquer() {
		return attaquer;
	}

	public void setAttaquer(boolean attaquer) {
		this.attaquer = attaquer;
		if (plateau.getPosition()!=null)
			try {
				selectionnerCase(plateau.getPosition().getX(), plateau.getPosition().getY());
			} catch (SelectionImpossible e) {} catch (FinDePartie e) {}
	}
	
}